package com.ruoyi.api.web;

import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.shop.domain.*;
import com.ruoyi.shop.service.*;
import com.ruoyi.shop.util.ImageUtils;
import com.ruoyi.shop.util.pay.PayStatus;
import com.ruoyi.shop.util.pay.UserOrderConstants;
import com.ruoyi.shop.util.pay.WXPayConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

/**
 * 作者: @author Alan Zhang
 * 时间: 2021/9/16 16:28
 * 描述:
 */
@Api(tags = "我的信息")
@RestController
@RequestMapping("/api/my")
public class ApiMyController extends ApiBaseController{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private WxPayService wxService;
    @Autowired
    private IShopUserOrderService shopUserOrderService;
    @Autowired
    private IShopUserFavoriteService shopUserFavoriteService;
    @Autowired
    private IShopUserService shopUserService;
    @Autowired
    private IShopCouponCodeService shopCouponCodeService;
    @Autowired
    private IShopUserAddressService shopUserAddressService;
    @Autowired
    private IShopProductCommentService shopProductCommentService;
    @Autowired
    private IShopCouponService shopCouponService;
    @Autowired
    private IShopCouponUsedRecordService shopCouponUsedRecordService;
    @Autowired
    private IShopPaymentRecordService shopPaymentRecordService;
    @Autowired
    private IShopRefundApplyService shopRefundApplyService;


    @ApiOperation("我的信息")
    @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String")
    @PostMapping("/userInfo")
    public AjaxResult userInfo()
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopUser userInfo = shopUserService.selectShopUserById(userOpenid.getUserId());
        if(userInfo == null){
            return AjaxResult.error("用户不存在");
        } else {
            return AjaxResult.success(userInfo);
        }

    }

    @ApiOperation("我的订单")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query",name = "status", value = "订单状态 1交易中、 2交易完成（但是可以申请退款） 、3取消交易 、4申请退款、 5拒绝退款、 6退款中、 7退款完成、 9交易结束", dataType = "Integer"),
    })
    @PostMapping("/order")
    public AjaxResult orderList(Integer status)
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopUserOrder param = new ShopUserOrder();
        param.setBuyerId(userOpenid.getUserId());
        param.setTradeStatus(status);
        List<ShopUserOrder> orderList = shopUserOrderService.selectShopUserOrderList(param);
        return AjaxResult.success(orderList);
    }


    @ApiOperation("用户取消订单")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query",name = "orderNo", value = "订单", required = true, dataType = "String"),
    })
    @GetMapping("/order/cancel")
    public AjaxResult orderCancel(String orderNo) throws WxPayException {
        ShopUserOpenid shopUserOpenid = shopUserIdByToken();

        ShopUserOrder shopUserOrder = shopUserOrderService.selectShopUserOrderByOrderNo(orderNo);

        if(shopUserOrder.isUnpay()) {
            WxPayOrderCloseResult result = wxService.closeOrder(orderNo);
            if (WXPayConstants.SUCCESS.equals(result.getResultCode())) {

                ShopUserOrder orderEntity = new ShopUserOrder();
                orderEntity.setId(shopUserOrder.getId());
                orderEntity.setPayStatus(PayStatus.FAILURE.getStatus());
                orderEntity.setTradeStatus(UserOrderConstants.TRADE_STATUS_CANCEL);
                orderEntity.setRemark("用户取消订单");

                shopUserOrderService.updateShopUserOrder(orderEntity);

                if(shopUserOrder.getPaymentId() != null) {
                    ShopPaymentRecord paymentRecord = shopPaymentRecordService.selectShopPaymentRecordById(shopUserOrder.getPaymentId());
                    if (paymentRecord.isPayPre()) {
                        ShopPaymentRecord paymentRecordEntity = new ShopPaymentRecord();
                        paymentRecordEntity.setId(paymentRecord.getId());
                        paymentRecordEntity.setPayStatus(PayStatus.FAILURE.getStatus());
                        paymentRecordEntity.setRemark("用户取消订单");

                        shopPaymentRecordService.updateShopPaymentRecord(paymentRecordEntity);
                    } else if(PayStatus.FAILURE.getStatus() == paymentRecord.getPayStatus()){
                        return AjaxResult.error("已取消");
                    }
                }

                return AjaxResult.success("订单取消成功");
            } else {
                logger.info(result.toString());
            }
        }
        return AjaxResult.success("订单取消失败");
    }


    @ApiOperation("订单申请退款")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query",name = "orderNo", value = "订单号", dataType = "Integer"),
            @ApiImplicitParam(paramType = "query",name = "type", value = "1、收到商品破损; 2、商品错发、漏发 ; 3、收到商品与描述不符 ; 4、其他 说明 ;", dataType = "Integer"),
            @ApiImplicitParam(paramType = "query",name = "reason", value = "退款原因", dataType = "String"),
            @ApiImplicitParam(paramType = "query",name = "file", value = "退款原因图片", dataType = "File"),
    })
    @PostMapping("/order/refund")
    public AjaxResult orderRefund( String orderNo, Integer type, String reason, @RequestParam("file") MultipartFile file) throws IOException {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopUserOrder order = shopUserOrderService.selectShopUserOrderByOrderNo(orderNo);
        if(order == null){
            return AjaxResult.error("订单不存在");
        }
        if(userOpenid.getUserId().equals(order.getBuyerId())){
            return AjaxResult.error("订单不属于该用户");
        }

        if(order.getTradeStatus() == UserOrderConstants.TRADE_STATUS_COMPLETED) {

            ShopRefundApply shopRefundApply = new ShopRefundApply();
            shopRefundApply.setOrderId(order.getId());
            shopRefundApply.setUserId(userOpenid.getUserId());
            shopRefundApply.setReason(reason);
            shopRefundApply.setType(type);
            if(file != null) {
                String imgUrl = ImageUtils.uploadRefund(file);
                shopRefundApply.setImgUrl(imgUrl);
            }
            shopRefundApplyService.insertShopRefundApply(shopRefundApply);
            return AjaxResult.success("申请退款成功，等待商家处理。");
        } else {

            return AjaxResult.error("申请退款失败");
        }

    }


    @ApiOperation("我的优惠券")
    @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String")
    @PostMapping("/coupon")
    public AjaxResult couponList()
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();
        ShopCouponCode param = new ShopCouponCode();
        param.setUserId(userOpenid.getUserId());

        List<ShopCouponCode> couponCodeList = shopCouponCodeService.selectShopCouponCodeList(param);
        return AjaxResult.success(couponCodeList);
    }


    @ApiOperation("领取优惠券")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "couponId", value = "优惠券ID", required = true, dataType = "Long"),
    })
    @GetMapping("/drawCoupon")
    public AjaxResult drawCoupon( Long couponId){
        ShopUserOpenid shopUserOpenid = shopUserIdByToken();

        AjaxResult result = shopCouponCodeService.drawCoupon(couponId, shopUserOpenid.getUserId());
        return result;
    }


    @ApiOperation("优惠券使用记录")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
    })
    @GetMapping("/usedCoupon")
    public AjaxResult useCoupon(){
        ShopUserOpenid shopUserOpenid = shopUserIdByToken();

        ShopCouponUsedRecord param = new ShopCouponUsedRecord();
        param.setUsedUserId(shopUserOpenid.getUserId());

        List<ShopCouponUsedRecord> list = shopCouponUsedRecordService.selectShopCouponUsedRecordList(param);
        return AjaxResult.success(list);
    }


    @ApiOperation("我的收藏")
    @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String")
    @PostMapping("/favorite")
    public AjaxResult favoriteList()
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopUserFavorite param = new ShopUserFavorite();
        param.setUserId(userOpenid.getUserId());
        List<ShopUserFavorite> userFavoriteList = shopUserFavoriteService.selectShopUserFavoriteList(param);
        return AjaxResult.success(userFavoriteList);
    }



    @ApiOperation("我的评价")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "productId", value = "产品Id", dataType = "Long"),
    })
    @PostMapping("/comment")
    public AjaxResult comment(Long productId)
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopProductComment param = new ShopProductComment();
        param.setUserId(userOpenid.getUserId());
        param.setProductId(productId);
        List<ShopProductComment> commentList = shopProductCommentService.selectShopProductCommentList(param);
        return AjaxResult.success(commentList);
    }


    @ApiOperation("对商品评价")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
            @ApiImplicitParam(name = "productId", value = "产品Id", dataType = "Long"),
            @ApiImplicitParam(name = "content", value = "评价内容", dataType = "String"),
    })
    @PostMapping("/write/comment")
    public AjaxResult writeProductComment(Long productId, String content)
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopProductComment productComment = new ShopProductComment();
        productComment.setUserId(userOpenid.getUserId());
        productComment.setProductId(productId);
        productComment.setContent(content);
        int rows = shopProductCommentService.insertShopProductComment(productComment);

        if(rows > 0){
            return AjaxResult.success("评价成功");
        } else {
            return AjaxResult.error("评价失败");
        }
    }


    @ApiOperation("我的地址")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
    })
    @PostMapping("/address")
    public AjaxResult addressList()
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopUserAddress param = new ShopUserAddress();
        param.setUserId(userOpenid.getUserId());
        List<ShopUserAddress> userAddressList = shopUserAddressService.selectShopUserAddressList(param);
        return AjaxResult.success(userAddressList);
    }

    @ApiOperation("新增地址")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
    })
    @PostMapping("/address/add")
    public AjaxResult addAddress(@RequestBody ShopUserAddress shopUserAddress)
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();
        shopUserAddress.setUserId(userOpenid.getUserId());

        int rows = shopUserAddressService.insertShopUserAddress(shopUserAddress);
        if(rows > 0){

            if(shopUserAddress.getWidthDefault()!= null && shopUserAddress.getWidthDefault() == 1){
                ShopUserAddress param = new ShopUserAddress();
                param.setUserId(userOpenid.getUserId());
                param.setWidthDefault(1);
                List<ShopUserAddress> list= shopUserAddressService.selectShopUserAddressList(param);
                for (ShopUserAddress entity:list) {
                    entity.setWidthDefault(0);

                    shopUserAddressService.updateShopUserAddress(entity);
                }
            }

            return AjaxResult.success("地址添加成功");
        } else {
            return AjaxResult.success("地址新增失败");
        }

    }

    @ApiOperation("修改地址")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
    })
    @PostMapping("/address/update")
    public AjaxResult updateAddress(@RequestBody ShopUserAddress shopUserAddress)
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        ShopUserAddress entity = shopUserAddressService.selectShopUserAddressById(shopUserAddress.getId());

        int rows = shopUserAddressService.updateShopUserAddress(shopUserAddress);
        if(rows > 0){
            if(entity.getWidthDefault() == 0 && shopUserAddress.getWidthDefault()!= null && shopUserAddress.getWidthDefault() == 1){
                ShopUserAddress param = new ShopUserAddress();
                param.setUserId(userOpenid.getUserId());
                param.setWidthDefault(1);
                List<ShopUserAddress> list= shopUserAddressService.selectShopUserAddressList(param);
                for (ShopUserAddress temp:list) {

                    temp.setWidthDefault(0);

                    shopUserAddressService.updateShopUserAddress(entity);
                }
            }
            return AjaxResult.success("地址修改成功");
        } else {
            return AjaxResult.success("地址修改失败");
        }

    }


    @ApiOperation("删除地址")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header",name = "token", value = "用户token", required = true, dataType = "String"),
            @ApiImplicitParam(paramType = "query",name = "id", value = "地址id", required = true, dataType = "Long"),
    })
    @PostMapping("/address/del")
    public AjaxResult delAddress(Long id)
    {
        ShopUserOpenid userOpenid = shopUserIdByToken();

        int rows = shopUserAddressService.deleteShopUserAddressById(id);
        if(rows > 0){
            return AjaxResult.success("地址删除成功");
        } else {
            return AjaxResult.success("地址删除失败");
        }
    }
}
